package com.apestech.formwork.run.core;

import com.apestech.formwork.xml.core.exec.SingleNode;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.run.datamapper.MappingData;
import com.apestech.framework.run.datamapper.SingleDataMappingModule;
import com.apestech.framework.run.modul.ExecSingleParam;
import com.apestech.framework.util.ExceptionUtil;
import com.apestech.framework.util.ReflectUtil;
import com.apestech.framework.util.StringUtil;

import java.util.ArrayList;

/**
 * 执行相关工具类
 *
 * @author hup
 * @create 2018-04-26-10:03
 */
public class ExecUtil extends StringUtil{

    public static Object execProcess(ExecSingleParam param, JSONObject input, Object classObj, SqlSession session) throws Exception {
        String type=param.getType();
        Object result=null;
        switch(type){
            case "method":
                String className=param.getClassName();
                String methodName=param.getMethodName();
                className=getDataValue(className, input);
                methodName=getDataValue(methodName, input);
                Object obj= ReflectUtil.getObject(className);
                if(input==null){
                    result=ReflectUtil.execMethod(obj, methodName);
                } else {
                    result=ReflectUtil.execMethod(obj, methodName, input);
                }
                break;
            case "query":
                if(session==null){
                    ExceptionUtil.exception(classObj,"execProcess","查询方式执行必需获取session！");
                }
                String queryId=getDataValue(param.getQueryId(), input);
                result=session.getForJSON().queryId(queryId, input);
                break;
            case "pricingProcess":
                if(input==null){
                    ExceptionUtil.exception(classObj,"execProcess","定价过程入参必填！");
                }
                if(session==null){
                    ExceptionUtil.exception(classObj,"execProcess","定价过程必需获取session！");
                }
                String pricingProcessId=getDataValue(param.getPricingProcessId(), input);
                //result=session.pricingProcess(input);
                break;
            case "json":
                //静态类调用
                result=null;
                break;
            case "ruleEngine":
                //静态类调用
                result=(JSONObject)param.getInput();
                break;
            case "condition":
                if(input==null){
                    ExceptionUtil.exception(classObj,"execProcess","条件类型入参必填！");
                }
                if(session==null){
                    ExceptionUtil.exception(classObj,"execProcess","条件类型必需获取session！");
                }
                String conditionId=getDataValue(param.getConditionId(), input);
                //result=session.pricingProcess(input);
                break;
            case "http":
                //静态类调用
                result=null;
                break;
        }
        return result;
    }

    public static JSONObject getData(ArrayList<SingleDataMappingModule> param, JSONObject input) throws Exception {
        if(param==null) return null;
        if("".equals(param)) return null;
        JSONObject in=null;
        MappingData data=new MappingData();
        data.setParams(param);
        in=data.getData(input);
        return in;
    }

    public static String getDataValue(String text, JSONObject input){
        if(hasBatisVariable(text)){
            ArrayList<String> list=getBatisVariableList(text);
            int len=list.size();
            for(int i=0; i<len; i++){
                String key=list.get(i);
                text=replaceBatisVariable(text, key, input.getString(key));
            }
        }
        return text;
    }

    public static boolean hasInput(SingleNode node){
        if("".equals(node.getParam().getInput()) && node.getWhileInput()==null){
            return false;
        }
        return true;
    }

    public static boolean hasOutput(SingleNode node){
        if("".equals(node.getParam().getOutput()) && node.getWhileOutput()==null){
            return false;
        }
        return true;
    }

    public static JSONObject getInput(SingleNode node, JSONObject data, SqlSession session) throws Exception {
        JSONObject map=null;
        if(node.getParam().hasInput()){
            map=getData((ArrayList<SingleDataMappingModule>) node.getParam().getInput(), data);
        } else {
            if(node.getWhileInput()!=null){
                map=getDataFromWhile(node, data, session);
            }
        }
        return map;
    }

    public static JSONObject getOutput(SingleNode node, JSONObject data, SqlSession session) throws Exception {
        JSONObject map=null;
        if(node.getParam().hasOutput()){
            map=getData((ArrayList<SingleDataMappingModule>) node.getParam().getOutput(), data);
        } else {
            if(node.getWhileInput()!=null){
                map=getDataFromWhile(node, data, session);
            }
        }
        return map;
    }

    public static JSONObject getDataFromWhile(SingleNode node, JSONObject data, SqlSession session) throws Exception {
        JSONObject map=null;
        SingleWhile swhile=new SingleWhile(node);
        swhile.setSqlSession(session);
        swhile.setInput(data);
        swhile.execute();
        map=swhile.getOutput();
        return map;
    }

}
